//
//  SuperSDK.m
//  SuperSDK
//
//  Created by wyht－ios－dev on 15/10/6.
//  Copyright © 2015年 WYHT. All rights reserved.
//

#import "SuperSDKInst.h"
#import "sys/utsname.h"
#include <ifaddrs.h>
#include <arpa/inet.h>
#import <AdSupport/AdSupport.h>
#import "SSDKDataKeys.h"
#import "SSDKErrorInfo.h"
#import "SSDKDelegateWrapper.h"
#import "SSDKEnum.h"
#import "SSDKDataHelper.h"
#import "SSDKHttpUtil.h"
#import "SSDKEventManager.h"
#import "SSDKEventKeys.h"
#import "SSDKUserManager.h"
#import "SSDKStatusManager.h"
#import "SuperSDKPluginTools/SSDKPluginLogUtil.h"
#import "SuperSDKPluginTools/SSDKPluginIPUtil.h"

@implementation SuperSDKInst

#pragma mark Static Arguments

static NSString *KEY_SDK_CONFIG_INFO_KEY = @"REMOTE_SDKCONFIG_ENABLE";
static NSString *KEY_SDK_URL = @"SURL";
static NSString *KEY_SDK_CHANNEL = @"SSDK_CHANNEL_ID";
static NSString *KEY_SDK_IS_LANDSCAPE = @"IS_LANDSCAPE";
static NSString *KEY_SSDK_CONFIG = @"SSDKConfig";
static NSString *KEY_SDK_CLASS=@"SDK_CLASS";

#pragma mark Singleton Method

static SuperSDKInst *instance = nil;

+ (id) getInstance {
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

#pragma mark - SDK Call Messages

- (void) initWithAppId:(NSString *)appId
              appSecret:(NSString *)appSecret
             privateKey:(NSString *)privateKey
           userDelegate:(id<SSDKDelegate>)userDelegate
           payDelegate:(id<SSDKDelegate>)payDelegate
             debugMode:(BOOL) debugMode {
    _appId = appId;
    _appSecret = appSecret;
    _privateKey = privateKey;
    _serverID=0;//默认是0
    
    //初始化客户端统计的信息
    [self initClientInfo];
    
    if (debugMode) {
        [[SSDKPluginLogUtil getInstance] setDebugMode:debugMode];
        [SSDKPluginLogUtil Log:@"SSDK_debugMode YES"];
        [SSDKPluginLogUtil Log:@"SSDK_startInit success"];
    }
    
    @try {
        NSDictionary *data = [[NSBundle mainBundle] infoDictionary];
        NSString *baseClassName=nil;
        NSDictionary *config = [data objectForKey:KEY_SSDK_CONFIG];
        BOOL remoteSDKConfigEnable = NO;
        _channelId = [config valueForKey:KEY_SDK_CHANNEL];
        _isLandscape = [[config valueForKey:KEY_SDK_IS_LANDSCAPE] boolValue];
        _sUrl = [config valueForKey:KEY_SDK_URL];
        baseClassName=[config valueForKey:KEY_SDK_CLASS];
        
        if(baseClassName==nil||_channelId==nil||_sUrl==nil)
        {
            
            SSDKErrorInfo *error = [[SSDKErrorInfo alloc] init];
            [error setError:@"Error: SDKConfig Get content Failed." withCode:INIT_FAIL];
            [SSDKUserDelegateWrapper initFail:error];
            return;
        }
        
        remoteSDKConfigEnable = [[config valueForKey:KEY_SDK_CONFIG_INFO_KEY] boolValue];
        [SSDKDataHelper setRemoteSDKConfigEnable:remoteSDKConfigEnable];
        
    }
    @catch (NSException *exception) {
        NSLog(@"Error: SDKConfig Read Failed.");
        return;
    }

    [self setUserDelegate:userDelegate payDelegate:payDelegate];
}

- (void) setUserDelegate:(id<SSDKDelegate>)userDelegate
             payDelegate:(id<SSDKDelegate>)payDelegate
{
    [[SSDKUserDelegateWrapper instance] setDelegate:userDelegate];
    [[SSDKPayDelegateWrapper instance] setDelegate:payDelegate];
    
    [SSDKPluginLogUtil Log:@"SSDK_setDelegate success"];
    
    if ([SSDKDataHelper remoteSDKConfigEnable]) {
        [SSDKConfigUtil postWithHttpDelegate: ^(SSDKBaseResData* resData){
            if ([resData isOk]) {
                [SSDKDataHelper setSdkConfig:resData.data];
                dispatch_async(dispatch_get_main_queue(), ^{
                    [SSDKPluginLogUtil Log:@"SSDK_init sdkResource"];
                    [SSDKEventManager postNotificationName:EVENT_INIT object:nil];
                });
            }
            else {
                [SSDKUserDelegateWrapper initFail:resData];
            }

        }];
    }
    else {
        dispatch_async(dispatch_get_main_queue(), ^{
            [SSDKPluginLogUtil Log:@"SSDK_init sdkResource"];
            [SSDKEventManager postNotificationName:EVENT_INIT object:nil];
        });
    }
}

- (void) login:(int)serverID loginReqUrl:(NSString *)loginReqUrl data:(NSString *)data
{
    if(serverID<0)
    {
        [SSDKPluginLogUtil Log:@"SSDK_login error serverID must bigger than 0!"];
        SSDKErrorInfo *errorInfo = [[SSDKErrorInfo alloc] init];
        [errorInfo setError:@"USER_LOGIN_FAIL"
                   withCode:USER_INFO_NULL
                    withMsg:@"serverID must bigger than 0!"];
        [SSDKUserDelegateWrapper loginFail:errorInfo];
        return;
    }
    
    _serverID=serverID;
    [self login:loginReqUrl data:data];
}

- (void) login:(NSString *)loginReqUrl
       data:(NSString *) data
{
    if(![[SSDKStatusManager getInstance] initSuccessFlag]) {
        [SSDKPluginLogUtil Log:@"SSDK_login error client must initial first!"];
        SSDKErrorInfo *errorInfo = [[SSDKErrorInfo alloc] init];
        [errorInfo setError:@"USER_LOGIN_FAIL"
                   withCode:SDK_INIT_FAILED
                    withMsg:@"client must initialize first!"];
        [SSDKUserDelegateWrapper loginFail:errorInfo];
        return;
    }
    
    _loginUrl =loginReqUrl;

    [SSDKDataHelper setLoginAppData:data];
    dispatch_async(dispatch_get_main_queue(), ^{
        [SSDKPluginLogUtil Log:[@"SSDK_login :" stringByAppendingString:data]];
        [SSDKEventManager postNotificationName:EVENT_LOGIN object:nil];
    });
}

- (void) login:(NSString *) data {
    [self login:nil data:data];
}

- (BOOL) isLogin {
    return [SSDKUserManager isLogin];
}

- (NSString *) uid {
    return [[[SSDKUserManager getInstance] curUserInfo] superSDKUid]==nil?@"":[[[SSDKUserManager getInstance] curUserInfo] superSDKUid];
}

- (NSString *) token {
    return [[[SSDKUserManager getInstance] curUserInfo] superSDKToken]==nil?@"":[[[SSDKUserManager getInstance] curUserInfo] superSDKToken];
}

- (void) destroy {
    _appId = nil;
    _appSecret = nil;
    _privateKey = nil;
    _loginUrl = nil;
    _sUrl = nil;
    _isLandscape = NO;
    _channelId = nil;
    instance = nil;
    
    [SSDKEventManager postNotificationName:EVENT_DESTROY object:nil];
    [SSDKPluginLogUtil Log:@"SSDK_destroy success"];
}

- (void) payWithPayInfo:(SSDKPayInfo *)payInfo {
    
    if (![[SSDKStatusManager getInstance] loginSuccessFlag]) {
        SSDKErrorInfo *errorInfo = [[SSDKErrorInfo alloc] init];
        [errorInfo setError:@"USER_INFO_NULL"
                   withCode:USER_INFO_NULL
                    withMsg:@"Please Login First!"];
        [SSDKPayDelegateWrapper payFail:errorInfo];
        return;
    }
    
    //防止多次重复支付
    if([[SSDKStatusManager getInstance] payingFlag])
        return;
    
//    float orderAmout=[[payInfo orderAmount] floatValue];
//    if (orderAmout==0) {
//        SSDKErrorInfo *errorInfo = [[SSDKErrorInfo alloc] init];
//        [errorInfo setError:@"ILLEGAL_ORDER_AMOUNT" withCode:ILLEGAL_SUPERSDK_UID withMsg:@"OrderAmount is illegal, please make sure OrderAmount is a number string and bigger than 0!"];
//        [SSDKPayDelegateWrapper payFail:errorInfo];
//        return;
//    }
    
    if (NO == [payInfo.uid isEqualToString:[instance uid]]) {
        SSDKErrorInfo *errorInfo = [[SSDKErrorInfo alloc] init];
        [errorInfo setError:@"ILLEGAL_SUPERSDK_UID" withCode:ILLEGAL_SUPERSDK_UID withMsg:@"Uid is not capable with current logged user, please relogin first!"];
        [SSDKPayDelegateWrapper payFail:errorInfo];
        return;
    }
    
    if(payInfo.serverId<=0)
    {
        [SSDKPluginLogUtil Log:@"SSDK_Pay error serverID must bigger than 0!"];
        SSDKErrorInfo *errorInfo = [[SSDKErrorInfo alloc] init];
        [errorInfo setError:@"PAY_INIT_FAIL"
                   withCode:PAY_USERINFO_FAIL
                    withMsg:@"serverID must bigger than 0!"];
        [SSDKPayDelegateWrapper payFail:errorInfo];
        return;
    }
    
    if(payInfo.cpOrderId!=nil)
    {
        if([payInfo.cpOrderId length]>30)
        {
            [SSDKPluginLogUtil Log:@"SSDK_Pay error cpOrderId's length must less than or equal to 30!"];
            SSDKErrorInfo *errorInfo = [[SSDKErrorInfo alloc] init];
            [errorInfo setError:@"PAY_INIT_FAIL"
                       withCode:PAY_USERINFO_FAIL
                        withMsg:@"cpOrderId's length must less than or equal to 30!"];
            [SSDKPayDelegateWrapper payFail:errorInfo];
            return;
        }
    }
    
    [SSDKPluginLogUtil Log:@"SSDK_pay start"];
    
    SSDKPaymentData *payment = [[SSDKPaymentData alloc] initWithPayInfo:payInfo];
    if(payInfo.paymentType!=nil) {
        //应对需要多种支付的情况
        [[payment extra] setObject:payInfo.paymentType forKey:PAYMENT_TYPE];
    }
    NSMutableDictionary *dic=[[NSMutableDictionary alloc] init];
    [dic setObject:payment forKey:SSDK_E_PAYINFO];
    [SSDKEventManager postNotificationName:EVENT_PAY object:dic];
}

- (NSMutableDictionary *) getClientInfo {
    //如果没有获取的ip，需要重新获取下ip地址
    if([[_clientInfo objectForKey:IP] isEqualToString:@"unknown"])
    {
        NSString *address = [SSDKPluginIPUtil getIPAddress:YES];
        if(address!=nil)
            [_clientInfo setObject:address forKey:IP];
        else
            [_clientInfo setObject:@"unknown" forKey:IP];
    }
    return _clientInfo;
}

- (void) initClientInfo
{
    _clientInfo=[[NSMutableDictionary alloc] init];
    //配置appVersion,appInnerVersion
    NSString *appVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    if(appVersion!=nil)
        [_clientInfo setObject:appVersion forKey:APP_VERSION];
    else
        [_clientInfo setObject:@"unknown" forKey:APP_VERSION];
    NSString *appInnerVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
    if(appInnerVersion!=nil)
        [_clientInfo setObject:appInnerVersion forKey:APP_INNER_VERSION];
    else
        [_clientInfo setObject:@"unknown" forKey:APP_INNER_VERSION];
    //包名
    NSString *bundleID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
    [_clientInfo setObject:(bundleID==nil?@"":bundleID) forKey:BUNDLE_ID];
    //idfa
    NSString *idfa = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
    [_clientInfo setObject:idfa forKey:SSDK_L_IDFA];
    //设备ID
    NSString *deviceID=[[NSUserDefaults standardUserDefaults] objectForKey:SSDK_R_DEVICE_ID];
    if(deviceID==nil) {
        if([idfa isEqualToString:@"00000000-0000-0000-0000-000000000000"]) {
            deviceID=[[NSUUID UUID] UUIDString];
        } else {
            deviceID=idfa;
        }
        [[NSUserDefaults standardUserDefaults] setObject:deviceID forKey:SSDK_R_DEVICE_ID];
    }
    [_clientInfo setObject:deviceID forKey:SSDK_L_DEVICE_ID];
    //IP(内网)
//    NSString *address = [SSDKPluginIPUtil getIPAddress:YES];
//    if(address!=nil)
//        [_clientInfo setObject:address forKey:IP];
//    else
//        [_clientInfo setObject:@"unknown" forKey:IP];
    //OSVersion
    NSString *osVersion = [[UIDevice currentDevice] systemVersion];
    if(osVersion!=nil)
        [_clientInfo setObject:osVersion forKey:OS_VERSION];
    else
        [_clientInfo setObject:@"unknown" forKey:OS_VERSION];
    //DeviceVersion
    struct utsname systemInfo;
    uname(&systemInfo);
    NSString *deviceVersion = [NSString stringWithFormat:@"%s", systemInfo.machine];
    if(deviceVersion!=nil)
        [_clientInfo setObject:deviceVersion forKey:DEVICE_VERSION];
    else
        [_clientInfo setObject:@"unknown" forKey:DEVICE_VERSION];
    //sdkVersion
    //sdkInnerVersion
    //FrameworkVersion
    NSDictionary *data = [[NSBundle mainBundle] infoDictionary];
    NSDictionary *config = [data objectForKey:SSDK_L_CONFIG];
    if (config!=nil) {
        NSString *sdkVersion=[config objectForKey:SSDK_L_SDK_VERSION];
        NSString *sdkInnerVersion=[config objectForKey:SSDK_L_SDK_INNER_VERSION];
        NSString *frameworkVersion=[config objectForKey:SSDK_L_FRAMEWORK_VERSION];
        if(sdkVersion!=nil)
            [_clientInfo setObject:sdkVersion forKey:SDK_VERSION];
        else
            [_clientInfo setObject:@"unknown" forKey:SDK_VERSION];
        if(sdkInnerVersion!=nil)
            [_clientInfo setObject:sdkInnerVersion forKey:SDK_INNER_VERSION];
        else
            [_clientInfo setObject:@"unknown" forKey:SDK_INNER_VERSION];
        if(frameworkVersion)
            [_clientInfo setObject:frameworkVersion forKey:FRAMEWORK_VERSION];
        else
            [_clientInfo setObject:@"unknown" forKey:FRAMEWORK_VERSION];
    } else {
        [_clientInfo setObject:@"unknown" forKey:SDK_VERSION];
        [_clientInfo setObject:@"unknown" forKey:SDK_INNER_VERSION];
        [_clientInfo setObject:@"unknown" forKey:FRAMEWORK_VERSION];
    }
}

@end
